package com.study.demo.disruptor.entity;

import com.lmax.disruptor.RingBuffer;

import java.nio.ByteBuffer;

public class LongEventProducer {

    //环形缓冲区,装载生产好的数据
    private final RingBuffer<LongEvent> ringBuffer;

    public LongEventProducer(RingBuffer<LongEvent> ringBuffer) {
        this.ringBuffer = ringBuffer;
    }

    /**
     * 将数据推入到缓冲区的方法：将数据装载到ringBuffer
     * 切记：一定要在设置值的地方加上
     * try{}finally{}
     * 否则如果数据发布不成功，最后数据会逐渐填满ringbuffer,最后后面来的数据根本没有办法调用可用空间，导致方法阻塞，占用CPU和内存，无法释放资源，最后导致服务器死机
     * 注意，最后的ringBuffer.publish方法必须包含在finally中以确保必须得到调用；如果某个请求的sequence未被提交，将会堵塞后续的发布操作或者其它的 producer。
     */
    public void publishData(ByteBuffer bb) {
        //获取下一个可用的序列号
        long sequence = ringBuffer.next();
        try {
            LongEvent event = ringBuffer.get(sequence);
            // 通过序列号获取空闲可用的 LongEvent
            event.set(bb.getInt(0)); //设置数值
        } finally {
            //数据发布，只有发布后的数据才会真正被消费者看见
            ringBuffer.publish(sequence);
        }
    }

}
